/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use crate::commands::auth_commands::{
    BeginAuthenticationCommandHandler, CancelAuthenticationCommandHandler,
    CheckReuseUnlockResultCommandHandler, DefaultBeginAuthenticationCommandExecutor,
    DefaultCancelAuthenticationCommandExecutor, DefaultCheckReuseUnlockResultCommandExecutor,
    DefaultGetAvailableStatusCommandExecutor, DefaultGetEnrolledStateCommandExecutor,
    DefaultGetValidSolutionCommandExecutor, DefaultUpdateAuthenticationResultCommandExecutor,
    GetAvailableStatusCommandHandler, GetEnrolledStateCommandHandler,
    GetValidSolutionCommandHandler, UpdateAuthenticationResultCommandHandler,
};
use crate::commands::credential_commands::{
    ClearUnavailableCredentialCommandHandler, DefaultClearUnavailableCredentialCommandExecutor,
    DefaultDeleteCredentialCommandExecutor, DefaultGetCredentialByIdCommandExecutor,
    DefaultGetCredentialCommandExecutor, DeleteCredentialCommandHandler,
    GetCredentialByIdCommandHandler, GetCredentialCommandHandler,
};
use crate::commands::enrollment_commands::{
    BeginEnrollmentCommandHandler, CancelEnrollmentCommandHandler, CloseSessionCommandHandler,
    DefaultBeginEnrollmentCommandExecutor, DefaultCancelEnrollmentCommandExecutor,
    DefaultCloseSessionCommandExecutor, DefaultOpenSessionCommandExecutor,
    DefaultUpdateAbandonResultCommandExecutor, DefaultUpdateEnrollmentResultCommandExecutor,
    OpenSessionCommandHandler, UpdateAbandonResultCommandHandler,
    UpdateEnrollmentResultCommandHandler,
};
use crate::commands::remote_auth_commands::{
    DefaultGetAuthResultFromMessageCommandExecutor,
    DefaultGetLocalScheduleFromMessageCommandExecutor, DefaultGetSignedExecutorInfoCommandExecutor,
    DefaultPrepareRemoteAuthCommandExecutor, GetAuthResultFromMessageCommandHandler,
    GetLocalScheduleFromMessageCommandHandler, GetSignedExecutorInfoCommandHandler,
    PrepareRemoteAuthCommandHandler,
};
use crate::commands::system_commands::{
    AddExecutorCommandHandler, DefaultAddExecutorCommandExecutor,
    DefaultDeleteExecutorCommandExecutor, DefaultInitCommandExecutor,
    DefaultSetGlobalConfigParamCommandExecutor,
    DefaultVerifyAuthTokenCommandExecutor, DeleteExecutorCommandHandler, InitCommandHandler, SetGlobalConfigParamCommandHandler, VerifyAuthTokenCommandHandler,
};
use crate::commands::user_commands::{
    DefaultDeleteUserCommandExecutor, DefaultEnforceDeleteUserCommandExecutor,
    DefaultGetAllExtUserInfoCommandExecutor, DefaultGetAllUserInfoCommandExecutor,
    DefaultGetUserInfoCommandExecutor, DeleteUserCommandHandler, EnforceDeleteUserCommandHandler,
    GetAllExtUserInfoCommandHandler, GetAllUserInfoCommandHandler, GetUserInfoCommandHandler,
};
use crate::common::constants::ErrorCode;
use crate::entry::user_auth_ffi::CommandId;
use crate::traits::command_manager::AccessPolicy;
use crate::traits::command_manager::CommandManagerRegistry;
use crate::Box;

pub fn register_init_command() -> Result<(), ErrorCode> {
    let registry = CommandManagerRegistry::get_mut();

    registry.register(Box::new(InitCommandHandler::new(
        CommandId::Init,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultInitCommandExecutor),
    )))?;

    Ok(())
}


pub fn register_other_commands() -> Result<(), ErrorCode> {
    let registry = CommandManagerRegistry::get_mut();

    registry.register(Box::new(InitCommandHandler::new(
        CommandId::Init,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultInitCommandExecutor),
    )))?;
    registry.register(Box::new(GetEnrolledStateCommandHandler::new(
        CommandId::GetEnrolledState,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetEnrolledStateCommandExecutor),
    )))?;
    registry.register(Box::new(SetGlobalConfigParamCommandHandler::new(
        CommandId::SetGlobalConfigParam,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultSetGlobalConfigParamCommandExecutor),
    )))?;
    registry.register(Box::new(AddExecutorCommandHandler::new(
        CommandId::AddExecutor,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultAddExecutorCommandExecutor),
    )))?;
    registry.register(Box::new(DeleteExecutorCommandHandler::new(
        CommandId::DeleteExecutor,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultDeleteExecutorCommandExecutor),
    )))?;
    registry.register(Box::new(VerifyAuthTokenCommandHandler::new(
        CommandId::VerifyAuthToken,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultVerifyAuthTokenCommandExecutor),
    )))?;
    registry.register(Box::new(GetUserInfoCommandHandler::new(
        CommandId::GetUserInfo,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetUserInfoCommandExecutor),
    )))?;
    registry.register(Box::new(GetAllUserInfoCommandHandler::new(
        CommandId::GetAllUserInfo,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetAllUserInfoCommandExecutor),
    )))?;
    registry.register(Box::new(GetAllExtUserInfoCommandHandler::new(
        CommandId::GetAllExtUserInfo,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetAllExtUserInfoCommandExecutor),
    )))?;
    registry.register(Box::new(DeleteUserCommandHandler::new(
        CommandId::DeleteUser,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultDeleteUserCommandExecutor),
    )))?;
    registry.register(Box::new(EnforceDeleteUserCommandHandler::new(
        CommandId::EnforceDeleteUser,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultEnforceDeleteUserCommandExecutor),
    )))?;
    registry.register(Box::new(GetCredentialCommandHandler::new(
        CommandId::GetCredential,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetCredentialCommandExecutor),
    )))?;
    registry.register(Box::new(GetCredentialByIdCommandHandler::new(
        CommandId::GetCredentialById,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetCredentialByIdCommandExecutor),
    )))?;
    registry.register(Box::new(DeleteCredentialCommandHandler::new(
        CommandId::DeleteCredential,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultDeleteCredentialCommandExecutor),
    )))?;
    registry.register(Box::new(ClearUnavailableCredentialCommandHandler::new(
        CommandId::ClearUnavailableCredential,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultClearUnavailableCredentialCommandExecutor),
    )))?;
    registry.register(Box::new(GetAvailableStatusCommandHandler::new(
        CommandId::GetAvailableStatus,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetAvailableStatusCommandExecutor),
    )))?;
    registry.register(Box::new(GetValidSolutionCommandHandler::new(
        CommandId::GetValidSolution,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetValidSolutionCommandExecutor),
    )))?;
    registry.register(Box::new(BeginAuthenticationCommandHandler::new(
        CommandId::BeginAuthentication,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultBeginAuthenticationCommandExecutor),
    )))?;
    registry.register(Box::new(CancelAuthenticationCommandHandler::new(
        CommandId::CancelAuthentication,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultCancelAuthenticationCommandExecutor),
    )))?;
    registry.register(Box::new(UpdateAuthenticationResultCommandHandler::new(
        CommandId::UpdateAuthenticationResult,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultUpdateAuthenticationResultCommandExecutor),
    )))?;
    registry.register(Box::new(CheckReuseUnlockResultCommandHandler::new(
        CommandId::CheckReuseUnlockResult,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultCheckReuseUnlockResultCommandExecutor),
    )))?;
    registry.register(Box::new(BeginEnrollmentCommandHandler::new(
        CommandId::BeginEnrollment,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultBeginEnrollmentCommandExecutor),
    )))?;
    registry.register(Box::new(CancelEnrollmentCommandHandler::new(
        CommandId::CancelEnrollment,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultCancelEnrollmentCommandExecutor),
    )))?;
    registry.register(Box::new(UpdateEnrollmentResultCommandHandler::new(
        CommandId::UpdateEnrollmentResult,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultUpdateEnrollmentResultCommandExecutor),
    )))?;
    registry.register(Box::new(OpenSessionCommandHandler::new(
        CommandId::OpenSession,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultOpenSessionCommandExecutor),
    )))?;
    registry.register(Box::new(CloseSessionCommandHandler::new(
        CommandId::CloseSession,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultCloseSessionCommandExecutor),
    )))?;
    registry.register(Box::new(UpdateAbandonResultCommandHandler::new(
        CommandId::UpdateAbandonResult,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultUpdateAbandonResultCommandExecutor),
    )))?;
    registry.register(Box::new(PrepareRemoteAuthCommandHandler::new(
        CommandId::PrepareRemoteAuth,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultPrepareRemoteAuthCommandExecutor),
    )))?;
    registry.register(Box::new(GetLocalScheduleFromMessageCommandHandler::new(
        CommandId::GetLocalScheduleFromMessage,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetLocalScheduleFromMessageCommandExecutor),
    )))?;
    registry.register(Box::new(GetAuthResultFromMessageCommandHandler::new(
        CommandId::GetAuthResultFromMessage,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetAuthResultFromMessageCommandExecutor),
    )))?;
    registry.register(Box::new(GetSignedExecutorInfoCommandHandler::new(
        CommandId::GetSignedExecutorInfo,
        AccessPolicy::AllowCaAccess,
        Box::new(DefaultGetSignedExecutorInfoCommandExecutor),
    )))?;

    Ok(())
}
